package com.mongo.secret;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;

import static com.mongo.util.SecretFactory.AES_SECRET;

/**
 * 提供Aes加解密
 * @author xiazhun
 * @create 2022/9/20
 */
@NoArgsConstructor
public class Aes implements Secret{

    private static volatile Aes INSTANCE;

    public static Aes getInstance() {
        if (INSTANCE == null) {
            //同步
            synchronized (Aes.class) {
                if (INSTANCE == null) {
                    INSTANCE = new Aes();
                }
            }
        }
        return INSTANCE;
    }

    @Override
    public String encrypt(String data, String key) {
        String res;
        try {
            KeyGenerator kg = KeyGenerator.getInstance("AES");
            if (StringUtils.isBlank(key)){
                kg.init(128, new SecureRandom(AES_SECRET.getBytes()));
            }else{
                kg.init(128, new SecureRandom(key.getBytes()));
            }
            SecretKey secretKey = kg.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec skey = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            byte[] byteContent = data.getBytes(StandardCharsets.UTF_8);
            cipher.init(Cipher.ENCRYPT_MODE, skey);
            byte[] result = cipher.doFinal(byteContent);
            res = Base64.getEncoder().encodeToString(result);
        }catch (Exception e){
            throw new IllegalArgumentException(e.getMessage());
        }
        return res;
    }

    @Override
    public String decode(String data, String key) {
       String res;
       try {
           KeyGenerator kg = KeyGenerator.getInstance("AES");
           if (StringUtils.isBlank(key)){
               kg.init(128, new SecureRandom(AES_SECRET.getBytes()));
           }else{
               kg.init(128, new SecureRandom(key.getBytes()));
           }
           SecretKey secretKey = kg.generateKey();
           byte[] enCodeFormat = secretKey.getEncoded();
           SecretKeySpec sKey = new SecretKeySpec(enCodeFormat, "AES");
           Cipher cipher = Cipher.getInstance("AES");
           cipher.init(Cipher.DECRYPT_MODE, sKey);
           byte[] result = cipher.doFinal(Base64.getDecoder().decode(data.getBytes()));
           res = new String(result, StandardCharsets.UTF_8);
       }catch (Exception e){
           throw new IllegalArgumentException(e.getMessage());
       }
        return res;
    }

}
